package com.lin.filegraph.utils.componentRule;

import com.lin.filegraph.utils.threshold.Threshold;
import com.lin.filegraph.utils.compdg.ComponentEdge;
import com.lin.filegraph.utils.compdg.ComponentGraph;
import com.lin.filegraph.utils.compdg.ComponentNode;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

/**
 * @description:
 * @author: linhuaixu
 * @time: 2023/5/18 15:52
 */

public class DetectMultiple {
    //	public void main(String args[]) {
//		List<ComponentNode>lists=new LinkedList<>();
//		List<String> listOfFiles1=new LinkedList();
//		listOfFiles1.add("1");
//		List<String> listOfFiles2=new LinkedList();
//		listOfFiles2.add("1");
//		listOfFiles2.add("2");
//		List<String> listOfFiles3=new LinkedList();
//		listOfFiles3.add("1");
//		listOfFiles3.add("2");
//		listOfFiles3.add("3");
//		List<String> listOfFiles4=new LinkedList();
//		listOfFiles4.add("1");
//		listOfFiles4.add("2");
//		listOfFiles4.add("3");
//		listOfFiles4.add("4");
//		lists.add(new ComponentNode("2", listOfFiles2, ""));
//		lists.add(new ComponentNode("1", listOfFiles1, ""));
//		lists.add(new ComponentNode("4", listOfFiles4, ""));
//		lists.add(new ComponentNode("3", listOfFiles3, ""));
//		lists=DetectMultiple.storedSortComp(null,lists);
//	}
    public static void OptimizeMutiComp(ComponentGraph graph)
    {
        List<ComponentNode> lists= storeNoSeparateAndNoRegionNoisfeatureComp(graph);
        if(lists.size()> Threshold.k1) {
            List<ComponentNode>SortedCompLists=storedSortComp(graph,lists);
            if(SortedCompLists.size()==0)
                return;
            ComponentNode csmallestnode=SortedCompLists.get(0);
            ComponentNode nearNode=getNearNode(csmallestnode,graph);
            if(nearNode!=null)
            {


                System.out.println("merge small scale comp");

                graph.mergeNodes(nearNode, csmallestnode);
                OptimizeMutiComp(graph);
            }
        }
    }
    private static ComponentNode getNearNode(ComponentNode csmallestnode,ComponentGraph graph) {
        // TODO Auto-generated method stub
        ComponentNode tempmax=null;double strength=0.0;
        if(graph.getOutEdgesOfComp(csmallestnode).size()!=0)
            for(ComponentEdge cedge:graph.getOutEdgesOfComp(csmallestnode)) {
                if(cedge.getDependence()>strength&&cedge.getPostComponent().isFeature()==false)
                {
                    strength=cedge.getDependence();
                    tempmax=cedge.getPostComponent();
                }
            }
        if(graph.getInEdgesOfComp(csmallestnode).size()!=0)
            for(ComponentEdge cedge:graph.getInEdgesOfComp(csmallestnode)) {
                if(cedge.getDependence()>strength&&cedge.getPreComponent().isFeature()==false)
                {
                    strength=cedge.getDependence();
                    tempmax=cedge.getPreComponent();
                }
            }
        return tempmax;
    }
    private void MergeSmallComp(List<ComponentNode> smallCompLists) {
        // TODO Auto-generated method stub

    }
    //store smallest compname
    public static List<ComponentNode> storeNoSeparateAndNoRegionNoisfeatureComp(ComponentGraph graph) {
        // TODO Auto-generated method stub
        List<ComponentNode>lists=new LinkedList();
        //组件数量过多

        for(ComponentNode cnode:graph.getAllComponents()) {
            if(cnode.isRegion()==false) {
                if(graph.getPostComponents(cnode).size()>0||graph.getPreComponents(cnode).size()>0)
                {
//						   ComponentNode NearestNode=searchNearestStrengthNode(cgAuto,cnode);
//						   cgAuto.mergeNodes(NearestNode,cnode);
//						   mergeComp(cgAuto);
                    if(cnode.isFeature()==false)
                        lists.add(cnode);
                }

            }
        }
        if(multiCompNum(lists.size(),Threshold.CompNumControl)) {
            return  lists;
        }
        return lists;
    }

    public static List<ComponentNode> storedSortComp(ComponentGraph graph,List<ComponentNode>lists){
        if(lists.size()==0)
            return null;
        Collections.sort(lists, new  Comparator<ComponentNode>(){

            @Override
            public int compare(ComponentNode arg0, ComponentNode arg1) {
                // TODO Auto-generated method stub
                if(arg0.getAllFiles().size()>arg1.getAllFiles().size())
                    return 1;
                if(arg0.getAllFiles().size()<arg1.getAllFiles().size())
                    return -1;
                return 0;
            }});
//	   List<ComponentNode>SmallCompLists=new LinkedList();
//	   for(int i=0;lists.size()>Threshold.k1&&(i<lists.size()-Threshold.k1);i++) {
//		   SmallCompLists.add(lists.get(i));
//	   }
        return lists;
    }
    private static ComponentNode searchNearestStrengthNode(ComponentGraph graph,ComponentNode cnode) {
//		// TODO Auto-generated method stub
//		double max=0.0;
//		ComponentNode maxcnode=null;
//		for(c)
        return null;
    }


    private static boolean multiCompNum(int size, int compnumcontrol) {
        // TODO Auto-generated method stub
        if(size>compnumcontrol)
            return true;
        return false;
    }
    //组件总数
    public static void OptimizeMutiComp1(ComponentGraph graph) {
        // TODO Auto-generated method stub
        List<ComponentNode>complist=graph.getAllComponents();
        if(complist.size()>Threshold.k1) {
            List<ComponentNode>SortedCompLists=storedSortComp(graph,complist);
            if(SortedCompLists.size()==0)
                return;
            int index=0;
            ComponentNode csmallestnode=SortedCompLists.get(index);
            ComponentNode nearNode=getNearNode(csmallestnode,graph);
            while(nearNode==null||index!=SortedCompLists.size()-1) {
                index++;
                if(index==SortedCompLists.size()) {
                    return ;
                }
                csmallestnode=SortedCompLists.get(index);
                nearNode=getNearNode(csmallestnode,graph);

            }
            if(nearNode!=null)
            {
                System.out.println("merge small scale comp");
                graph.mergeNodes(nearNode, csmallestnode);
                OptimizeMutiComp1(graph);
            }
        }

    }

}

